﻿#include<iostream>
#include<string>
using namespace std;
//class Person
//{
//protected:
//	string _name; // 姓名
//	string _sex;  // 性别
//	int _age;  // 年龄
//
//};
//class Student : public Person
//{
//public:
//	int _No; // 学号
//};
//int main()
//{
//	Student sobj;
//	// 1.派⽣类对象可以赋值给基类的指针/引⽤
//
//	Person * pp = &sobj;
//	Person& rp = sobj;
//	Person pobj = sobj;
//    // ⽣类对象可以赋值给基类的对象是通过调⽤后⾯会讲解的基类的拷⻉构造完成的
//    //2.基类对象不能赋值给派⽣类对象，这⾥会编译报错
//	sobj = pobj;
//	return 0;
//}


//class Person
//{
//public:
//	void Print()
//	{
//		cout << "我是基类中的Print函数" << endl;
//	}
//};
//class Student : public Person
//{
//public:
//	void Print()
//	{
//		cout <<"我是派生类中的Print函数" << endl;
//	}
//};
//int main()
//{
//	Student s1;
//	s1.Person::Print();
//	return 0;
//};

//class A
//{
//public:
//	//这里基类没有默认构造函数需要传递参数
//	A(string _name)
//	{
//		name = _name;
//	}
//
//	A& operator=(A& _a)
//	{
//		if (this != &_a)
//		{
//			name = _a.name;
//		}
//		return *this;
//	}
//	string name;
//};
//class B : public A
//{
//public:
//	B(int _n1,string _name)
//		:A(_name)
//		,n1(_n1)
//	{}
//	B& operator=(B& _b)
//	{
//		if (this != &_b)
//		{
//			A::operator=(_b);
//			n1 = _b.n1;
//		}
//		return *this;
//	}
//	void Print()
//	{
//		cout << name << n1 << std::endl;
//	}
//private:
//	int n1;
//};
//int main()
//{
//	B ss(18,"张三");
//	B pp=ss;
//	pp.Print();
//	return 0;
//};

//class Student;
//class Person
//{
//public:
//	friend void Display(const Person& p, const Student& s);
//protected:
//	string _name; // 姓名
//
//};
//class Student : public Person
//{
//protected:
//	int _stuNum; // 学号
//
//};
//void Display(const Person& p, const Student& s)
//{
//	cout << p._name << endl;
//	cout << s._stuNum << endl;
//}
//int main()
//{
//	Person p;
//	Student s;
//	// 编译报错：error C2248 : “Student::_stuNum” :⽆法访问protected成员
//    // 解决⽅案：Display也变成Student的友元即可
//	Display(p, s);
//	return 0;
//}

//class Person
//{
//public:
//	string _name; // 姓名
//
//};
//class Student : public Person
//{
//protected:
//	int _num; //学号
//
//};
//class Teacher : public Person
//{
//protected:
//	int _id; // 职⼯编号
//
//};
//class Assistant : public Student, public Teacher
//{
//protected:
//	string _majorCourse; // 主修课程
//
//};
//int main()
//{
//	// 编译报错：error C2385 :对“_name”的访问不明确
//	Assistant a;
//	a._name = "peter";
//	// 需要显⽰指定访问哪个基类的成员可以解决⼆义性问题，但是数据冗余问题⽆法解决
//	a.Student::_name = "xxx";
//	a.Teacher::_name = "yyy";
//	return 0;
//}

//class Base1 { public:  int _b1; };
//class Base2 { public:  int _b2; };
//class Derive : public Base1, public Base2 { public: int _d; };
//int main()
//{
//	Derive d;
//	Base1* p1 = &d;
//	Base2* p2 = &d;
//	Derive* p3 = &d;
//	return 0;
//}

// Tire(轮胎)和Car(⻋)更符合has - a的关系
//class Tire {
//protected:
//	// 品牌
//	string _brand = "Michelin";  
//	// 尺⼨
//	size_t _size = 17;
//};
//class Car {
//protected:
//	string _colour = "⽩⾊";           
//	string _num = "陕ABIT00";         
//	Tire _t1;
//	Tire _t2;
//	Tire _t3;
//	Tire _t4;
//};
//
//
//class BMW : public Car {
//public:
//	void Drive() 
//	{
//		cout << "好开操控" << endl; 
//	}
//};
//// Car和BMW / Benz更符合is - a的关系
//class Benz : public Car {
//public:
//	void Drive()
//	{
//		cout << "好坐舒适" << endl; 
//	}
//};
//
//template<class T>
//class vector
//{};
//// stack和vector的关系，既符合is - a，也符合has - a
//template<class T>
//class stack : public vector<T>
//{};
//template<class T>
//class stack
//{
//public:
//	vector<T> _v;
//};
//int main()
//{
//	return 0;
//}

//class Person
//{
//public:
//	virtual void BuyTicket() {
//		cout << "买票全价" << endl;
//	}
//};
//
//class Student :public Person
//{
//public:
//	virtual void BuyTicket() {
//		cout << "买票半价" << endl;
//	}
//};

//#include <iostream>
//using namespace std;
//
//class Base {
//public:
//    // 基类虚函数，缺省参数为10
//    virtual void show(int num = 10) {
//        cout << "Base: " << num << endl;
//    }
//};
//
//class Derived : public Base {
//public:
//    // 派生类重写虚函数，缺省参数为20（但不会生效）
//    void show(int num = 20) override {
//        cout << "Derived: " << num << endl;
//    }
//};
//
//int main() {
//    Base* ptr = new Derived();  // 基类指针指向派生类对象
//
//    ptr->show();  // 调用的是Derived::show()，但缺省参数用Base的10
//    // 输出：Derived: 10（而非20）
//
//    delete ptr;
//    return 0;
//}

//class A
//{
//public:
//	virtual void func(int val = 1) { std::cout << "A->" << val << std::endl; }
//	void test() { func(); }
//};
//class B : public A
//{
//public:
//	void func(int val = 0) { std::cout << "B->" << val << std::endl; }
//};
//int main(int argc, char* argv[])
//{
//	B* p = new B;
//	p->test();
//	return 0;
//}

//class Base {
//public:
//    void printAddr() {
//        cout << "Base::this = " << this << endl; // this指向调用者对象
//    }
//};
//
//class Derived : public Base {
//public:
//    void showAddr() {
//        cout << "Derived::this = " << this << endl; // this指向自身
//    }
//};
//
//int main() {
//    Derived d;
//    d.printAddr();  // 调用继承的Base成员函数
//    d.showAddr();   // 调用Derived自己的成员函数
//    return 0;
//}

//class A {
//public:
//	virtual void Function1()
//	{
//		cout << "基类的虚函数" << endl;
//	}
//};
//class B :public A{
//public:
//	//派生类B重写A中的虚函数，虚函数表中Function1的地址与A不同
//	virtual void Function1()
//	{
//		cout << "重写基类的虚函数" << endl;
//	}
//};
//class C :public A {
//public:
//	//派生类C不重写A中的虚函数，虚函数表中Function1的地址与A相同
//};
//int main()
//{
//	A p1;
//	B p2;
//	C p3;
//	return 0;
//}

//class A
//{
//public:
//	virtual ~A()
//	{
//		cout << "~A()" << endl;
//	}
//};
//class B : public A {
//public:
//	~B()
//	{
//		cout << "~B()->delete:" << _p << endl;
//		delete _p;
//	}
//protected:
//	int* _p = new int[10];
//};
//int main()
//{
//	A* p2 = new B;
//	// 只有派⽣类B的析构函数重写了A的析构函数，下⾯的delete对象调⽤析构函数，才能构成多态，
//	//才能保证p1和p2指向的对象正确的调⽤析构函数。
//	delete p2;
//	return 0;
//}

//class Car {
//public:
//	virtual void Dirve()
//	{}
//};
//
//class Benz :public Car {
//public:
//	//这里由于类名写错没有构成重写，编译器检查后报错
//	virtual void Drive() override {
//		cout << "Benz舒适" << endl; }
//	};
//int main()
//{
//	return 0;
//}

#include <iostream>
using namespace std;

class Animal {
public:
    // 基类虚函数
    virtual void speak() {
        cout << "动物发出声音" << endl;
    }
    virtual ~Animal() {} // 虚析构函数，确保动态绑定析构
};

class Dog : public Animal {
public:
    // 重写基类虚函数
    void speak() override {
        cout << "狗叫：汪汪汪" << endl;
    }
};


// 接收基类引用，体现多态
void makeSound(Animal* animal) {
    animal->speak(); // 动态绑定：调用实际对象的speak()
}

int main() {
    Animal animal;
    Dog dog;

    makeSound(&animal); // 输出：动物发出声音（实际类型Animal）
    makeSound(&dog);    // 输出：狗叫：汪汪汪（实际类型Dog）

    return 0;
}